#include<iostream>
#include<string>
#include<sys/types.h>
#include<sys/time.h>
#include<unistd.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<sys/stat.h>
#include<cstdio>
#include<cstring>
#include<fcntl.h>
#include<signal.h>
#include<pthread.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<unordered_map>
#include<netinet/in.h>
#include<vector>
#include<arpa/inet.h>
#include<sys/wait.h>
#include<functional>
#include <semaphore.h>
#include<jsoncpp/json/json.h>
#include<sys/select.h>
#include"Log.hpp"
using namespace std;
static unordered_map<string, string> suffix_info = {
    {".html", "text/html"},
    {".css", "text/css"},
    {".js", "application/javascript"},
    {".jpg", "application/x-jpg"},
    {".xml", "application/xml"},
};
class Util
{
public:
    static void ReadLine(int sock,string& request_line)
    {
        char ch = 'x';
        while (ch != '\n')
        {
            int n = recv(sock, &ch, 1, 0);
            if (n > 0)
            {
                if (ch == '\r') // 不将'\r'字符存入请求行中
                {
                    recv(sock, &ch, 1, MSG_PEEK);   
                    if (ch == '\n')
                    {
                        recv(sock, &ch, 1, 0);
                    }
                    else
                    {
                        ch = '\n';
                    }
                }
                request_line.push_back(ch);
            }
        }
    }
    static void DivideThreeLine(const string& line,string&method,string& version,string&uri,char ch)
    {
         int pos1=line.find(ch);
         int pos2=line.rfind(ch);
         method=line.substr(0,pos1);
         uri=line.substr(pos1+1,pos2-pos1-1);
         version=line.substr(pos2+1);
    }
    static void DivideKV(const string& line,unordered_map<string,string>&header_kv,string ch)
    {
        int pos=line.find(ch);
        string key=line.substr(0,pos);
        string val=line.substr(pos+ch.size());
        header_kv[key]=val;
    }
    static void CutTwoLine(const string& line,string& line_front,string& line_back,string ch)
    {
        int pos=line.find(ch);
        line_front=line.substr(0,pos);
        line_back=line.substr(pos+ch.size());
    }
    static string SearchSuffix(const string&path)
    {
        int pos=path.rfind('.');
        if(pos==string::npos)
        {
            return ".html";
        }
        else
        {
            return path.substr(pos);
        }
    }
    static string Suffix2Desc(const string&suffix)
    {
        return suffix_info[suffix];
    }
};